home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_2 / quickqso < prev    next >
Internet Message Format  |  1995-03-31  |  5KB

  1. From madler@tybalt.caltech.edu Fri Apr  6 22:39:21 1990
  2. From: madler@tybalt.caltech.edu (Mark Adler)
  3. Newsgroups: comp.sys.handhelds
  4. Subject: A quicker quicksort for the HP-48SX
  5. Date: 5 Apr 90 19:30:12 GMT
  6. Distribution: comp.sys.handhelds
  7. Organization: California Institute of Technology, Pasadena
  8.  
  9. With Alonzo's helpful comments about what operations are fast on the
  10. HP-48SX, and why, I wrote a quicksort program faster than Alonzo's.
  11. The speed increase comes from a different strategy (not putting the
  12. sublists on the bottom of the stack), tighter inner loops (index
  13. bounds do not have to be checked), a median approach to selecting the
  14. middle element, and a final insertion sort pass to sort short
  15. subfiles.
  16.  
  17. I tested three sorts: QSORT, ASORT, and SORT where QSORT is Alonzo's
  18. original, ASORT is QSORT modified to stop at sublists of length 24 or
  19. less and then do an insertion sort, and SORT is my version.  (SORT
  20. stops at sublists of length 20---the values 20 and 24 minimize the
  21. execution times of the respective sorts.)  They were all tested on
  22. lists of 500 reals and 50 reals (generated using RAND) with about 18K
  23. free before the list was made, and with lastargs turned off (flag -55
  24. set).  The list was stored in a global and then recalled to the
  25. stack, as per Alonzo's suggestion.  The test for 50 elements were
  26. done for 10 different random lists each and the number that follows
  27. is the standard deviation for the tests.  The times are in min:sec or
  28. just seconds:
  29.  
  30. sort       500     50
  31.  
  32. QSORT     3:55  10.37 (0.71)
  33. ASORT     3:35   7.85 (0.68)
  34. SORT      2:45   7.13 (0.31)
  35.  
  36. SORT can be modified to use a different comparison operator than ">"
  37. by changing the occurences of "IF DUP2 >" to "IF DUP2 GT", "PICK >"
  38. to "PICK GT", and "PICK <" to "PICK SWAP GT" in QPART, and "PICK >"
  39. to "PICK GT" in SORT, where GT is a program or expression that
  40. returns zero if stack entry 2 is less than or equal to stack entry
  41. one, or non-zero otherwise.
  42.  
  43. Mark Adler
  44. madler@tybalt.caltech.edu
  45.  
  46. Here are the programs:
  47.  
  48. %%HP: T(3)A(R)F(.);
  49. @ SORT crc #DBF1h length 112.5
  50. @ Use QPART to do a quicksort up to subfiles of length 20, and then do
  51. @ one pass of an insertion sort to sort the subfiles.
  52. \<< OBJ\-> \-> n                        @ put list on stack
  53.   \<< n 2 QPART                         @ do quicksort
  54.       2 n FOR j                         @ do insertion sort
  55.         j ROLL j 2 +                    @ get element j
  56.         WHILE                           @ assuming [1]..[j-1] is sorted,
  57.           DUP2 PICK >                   @  find where element j goes
  58.         REPEAT
  59.           1 -
  60.         END
  61.         2 - ROLLD                       @ put element j there
  62.       NEXT
  63.       n \->LIST                         @ convert back to list
  64.   \>>
  65. \>>
  66.  
  67. %%HP: T(3)A(R)F(.);
  68. @ QPART crc #16E0h length 389
  69. @ Given a partition of the stack, split it into two partitions so that
  70. @ all the entries in the first one are less than or equal to the entries
  71. @ in the second one, and then call this routine recusively for each of
  72. @ those partitions.  If a partition is 20 or fewer elements, then do
  73. @ nothing and end the recursion.  A final pass of an insertion sort will
  74. @ sort the remaining short partitions more efficiently.
  75. \<<
  76.   IF DUP2 - 18 > THEN                   @ sort if more than 20 elements
  77.     @ sort the portion of the stack from level l to level r (after
  78.     @  l and r are pulled off the stack).
  79.     \-> r l \<<                         @ (l is really l+1)
  80.       @ sort [l], [m], [r] so that [l] >= [m] >= [r] where they are
  81.       @  picked from the start, middle, and end of the sublist.
  82.       r l + 2 / FLOOR ROLL              @ (FLOOR needed since l is l+1)
  83.       l ROLL
  84.       IF DUP2 > THEN SWAP END
  85.       l ROLLD r ROLL
  86.       IF DUP2 > THEN
  87.         r
  88.       ELSE
  89.         SWAP r ROLLD l ROLL
  90.         IF DUP2 > THEN SWAP END
  91.         l
  92.       END
  93.       ROLLD
  94.       @ start sorting inside [l], [r].
  95.       r 3 + SWAP l 3 +
  96.       @ put [m] in list so that [i] >= [m] >= [j] for i < j.
  97.       WHILE                             @ stack is i+4,[m],j+4,list...
  98.         WHILE 1 + DUP2 PICK < REPEAT END        @ now [m] >= [i]
  99.         SWAP ROT
  100.         WHILE 1 - DUP2 PICK > REPEAT END        @ now [j] >= [m]
  101.         ROT DUP2 >                      @ until j <= i
  102.       REPEAT                            @ stack is i+4,j+4,[m],list...
  103.         DUP2 ROLL OVER ROLL             @ swap [i], [j]
  104.         4 PICK 1 + ROLLD OVER ROLLD
  105.         4 ROLLD SWAP DROP               @ stack is i+4,[m],j+4,list...
  106.       END
  107.       DROP 2 - SWAP OVER ROLLD          @ put [m] after [j]
  108.       @ sort the sublists [j+2..r] and [l..j] by calling this program
  109.       @  recursively.
  110.       r SWAP DUP 'r' STO 1 + QPART
  111.       r 2 - l QPART
  112.     \>>
  113.   ELSE
  114.     DROP2                               @ not sorting---trash r and l
  115.   END
  116. \>>
  117.  
  118.